package com.bobo.web.provider.util.commutils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class DateTimeUtils {
	private static final Logger logger = LoggerFactory.getLogger(DateTimeUtils.class.getSimpleName());

	public final static DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
	public final static DateFormat DATE_FORMAT2 = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
	public final static DateFormat DATE_FORMAT3 = new SimpleDateFormat("MMM dd", Locale.US);
	public final static DateFormat DATE_FORMAT4 = new SimpleDateFormat("MM-dd", Locale.getDefault());
	public final static DateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm", Locale.getDefault());
	public final static DateFormat TIME_FORMAT2 = new SimpleDateFormat("hh:mma", Locale.US);
	public final static DateFormat TIME_FORMAT3 = new SimpleDateFormat("MM-dd HH:mm", Locale.getDefault());
	public final static DateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
	public final static DateFormat DATETIME_FORMAT2 = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
	public final static DateFormat DATETIME_FORMAT3 = new SimpleDateFormat("MMM dd, hh:mma", Locale.US);
	public final static DateFormat DATETIME_FORMAT4 = new SimpleDateFormat("EEEE, MMM dd, hh:mma", Locale.US);
	public final static DateFormat DATETIME_FORMAT5 = new SimpleDateFormat("HH:mm", Locale.getDefault());
	public final static DateFormat DATETIME_FORMAT6 = new SimpleDateFormat("MMddHHmm", Locale.getDefault());
	public final static DateFormat DATETIME_FORMAT7 = new SimpleDateFormat("yyyyMMddHHmm", Locale.getDefault());
	public static final String FORMAT_YEAR_MONTH_DEFAULT = "yyyyMM";
	public static final String FORMAT_YEAR_MONTH_DAY_DEFAULT = "yyyy-MM-dd";
	public static final DateTimeFormatter PARSER_YYYYMMDDHHMMSS = DateTimeFormat.forPattern("yyyyMMddHHmmss");
	public static final DateTimeFormatter PARSER__YMDHMS = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
	public static final DateTimeFormatter PARSER__YYYYMMDD = DateTimeFormat.forPattern("yyyyMMdd");
	public static final DateTimeFormatter PARSER_YYYY_MM_DD = DateTimeFormat.forPattern("yyyy-MM-dd");
	public static final FastDateFormat FORMAT_YYYYMMDDHHMMSS = FastDateFormat.getInstance("yyyyMMddHHmmss");

	public static final FastDateFormat FORMAT_MMDDHHMMSS = FastDateFormat.getInstance("MMddHHmmss");

	public static final FastDateFormat FORMAT_YMDHMS = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");

	public static final FastDateFormat FORMAT_YYYYMMDD = FastDateFormat.getInstance("yyyyMMdd");

	public static final FastDateFormat FORMAT_YYYY_MM_DD = FastDateFormat.getInstance("yyyy-MM-dd");


	/**
	 * 超过时间是否按照id查询UA
	 * @Author:ALong (ZengWeiLong)
	 * @return
	 * boolean
	 * @date 2016年5月12日
	 */
	public static boolean isSearchById(){
		Integer ctime = Integer.parseInt(new SimpleDateFormat("yyyyMMdd").format(new Date()));
		return ctime > 20160420;
	}

	public static Date parse(String string, DateFormat format) {
		Date date = null;

		SimpleDateFormat sdf = getSimpleDateFormat(format);

		try {
			if(StringUtils.isEmpty(string)){
				return null;
			}
			date = sdf.parse(string);
		} catch (ParseException e) {
			if (format.equals(DATE_FORMAT) || format.equals(DATE_FORMAT2)) {
				logger.error("Error when parsing date from string: " + string);
			} else if (format.equals(TIME_FORMAT)) {
				logger.error("Error when parsing time from string: " + string);
			} else if (format.equals(DATETIME_FORMAT) || format.equals(DATETIME_FORMAT2) ||format.equals(DATETIME_FORMAT3)) {
				logger.error("Error when parsing datetime from string: " + string);
			}
		}

		return date;
	}

	private static SimpleDateFormat getSimpleDateFormat(DateFormat format) {
		SimpleDateFormat sdf = null;
		if(DATE_FORMAT.equals(format)){
			sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
		}else if(DATE_FORMAT2.equals(format)){
			sdf = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
		}else if(DATE_FORMAT3.equals(format)){
			sdf = new SimpleDateFormat("MMM dd", Locale.US);
		}else if(DATE_FORMAT4.equals(format)){
			sdf = new SimpleDateFormat("MM-dd", Locale.getDefault());
		}else if(TIME_FORMAT.equals(format)){
			sdf = new SimpleDateFormat("HH:mm", Locale.getDefault());
		}else if(TIME_FORMAT2.equals(format)){
			sdf = new SimpleDateFormat("hh:mma", Locale.US);
		}else if(TIME_FORMAT3.equals(format)){
			sdf = new SimpleDateFormat("MM-dd HH:mm", Locale.getDefault());
		}else if(DATETIME_FORMAT.equals(format)){
			sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
		}else if(DATETIME_FORMAT2.equals(format)){
			sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
		}else if(DATETIME_FORMAT3.equals(format)){
			sdf = new SimpleDateFormat("MMM dd, hh:mma", Locale.US);
		}else if(DATETIME_FORMAT4.equals(format)){
			sdf = new SimpleDateFormat("EEEE, MMM dd, hh:mma", Locale.US);
		}else if(DATETIME_FORMAT5.equals(format)){
			sdf = new SimpleDateFormat("HH:mm", Locale.getDefault());
		}else if(DATETIME_FORMAT6.equals(format)){
			sdf = new SimpleDateFormat("MMddHHmm", Locale.getDefault());
		}else if(DATETIME_FORMAT7.equals(format)){
			sdf = new SimpleDateFormat("yyyyMMddHHmm", Locale.getDefault());

		}
		return sdf;
	}

	public static String format(Date date, String pattern){
		return format(date, pattern, null);
	}

	public static String format(Date date, String pattern, Locale locale) {
		String dateStr = "";

		if(locale == null){
			locale = Locale.getDefault();
		}
		if(StringUtils.isBlank(pattern)){
			pattern = "yyyy-MM-dd HH:mm:ss";
		}
		if(date!=null){
			DateFormat format = new SimpleDateFormat(pattern, locale);
			dateStr = format.format(date);
		}
		return dateStr;
	}
	public static String format(Date date, DateFormat format) {
		if (date == null) {
			return null;
		}
		SimpleDateFormat sdf = getSimpleDateFormat(format);
		return sdf.format(date);
	}

	public static String format(Date date, DateFormat format, TimeZone tz) {
		SimpleDateFormat sdf = getSimpleDateFormat(format);
		if (format!= null && tz != null){
			sdf.setTimeZone(tz);
		}
		return (date == null ? null : sdf.format(date));
	}

	public static Date getNthMinutesLater(int n) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MINUTE, n);
		return calendar.getTime();
	}

	public static Date getNthMinutesLater(Date date, int n) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.MINUTE, n);
		return calendar.getTime();
	}

	public static Date getBeginningOfThisMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getBeginningOfNextMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MONTH, 1);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND,0);
		return calendar.getTime();
	}

	public static Date getBeginningOfNextNextMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MONTH, 2);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static Date getBeginningOfTheDay() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, 0);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getNthHourLater(int n) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.HOUR_OF_DAY, n);
		return calendar.getTime();
	}

	public static Date getTomorrow() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getTheBeginOfNthDaysBefore(int n) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, -n);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}
	public static Date getTheEndOfNthDaysBefore(int n) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, -n);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		return calendar.getTime();
	}

	public static Date getTomorrow(int interval) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, 1);
		calendar.set(Calendar.HOUR_OF_DAY, interval);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getToday(int interval) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, 0);
		calendar.set(Calendar.HOUR_OF_DAY, interval);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getToday() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, 0);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getPrevMinutes(int offset) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MINUTE, -offset);
		return calendar.getTime();
	}

	public static Date getYesterday(int interval) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, -1);
		calendar.set(Calendar.HOUR_OF_DAY, interval);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getTheDayAfterTomorrow() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, 2);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static Date getNextDay(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.DATE, 1);
		return cal.getTime();
	}

	public static Date getNextMonth(Date date){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.MONTH, 1);
		return cal.getTime();
	}

	public static Date getDateByOffset(int dayOffset, int minuteOffset){
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, dayOffset);
		calendar.add(Calendar.MINUTE, minuteOffset);
		return calendar.getTime();
	}

	public static Date getDateByOffset(int dayOffset,int hourOffset, int minuteOffset){
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, dayOffset);
		calendar.add(Calendar.HOUR, hourOffset);
		calendar.add(Calendar.MINUTE, minuteOffset);
		return calendar.getTime();
	}

	public static Boolean isBetween(Date date, Date start, Date end){
		return date.compareTo(start) ==1 && date.compareTo(end) == -1;
	}

	/**
	 * 调日期整天数、分钟
	 * @param date
	 * @param dayOffset
	 * @param minuteOffset
	 * @return
	 */
	public static Date getDateByOffset(Date date ,int dayOffset, int minuteOffset){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		if(dayOffset!=0){
			calendar.add(Calendar.DATE, dayOffset);
		}
		if(minuteOffset!=0){
			calendar.add(Calendar.MINUTE, minuteOffset);
		}
		return calendar.getTime();
	}

	public static Date getDateByOffset(Date date ,int monthOffset, int dayOffset, int minuteOffset){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		if(dayOffset!=0){
			calendar.add(Calendar.DATE, dayOffset);
		}
		if(minuteOffset!=0){
			calendar.add(Calendar.MINUTE, minuteOffset);
		}
		if(monthOffset!=0){
			calendar.add(Calendar.MONTH, monthOffset);
		}
		return calendar.getTime();
	}

	public static Date getNextNthMonday(int n) {
		Calendar calendar = Calendar.getInstance();
		if(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
			calendar.add(Calendar.WEEK_OF_YEAR, -1);
		}
		calendar.add(Calendar.WEEK_OF_YEAR, n);
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static Date getLastMonday() {
		Calendar calendar = Calendar.getInstance();

		if(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
			calendar.add(Calendar.WEEK_OF_YEAR, -1);
		}
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		calendar.add(Calendar.DATE, -7);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static Date getThisMonday() {
		Calendar calendar = Calendar.getInstance();

		if(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
			calendar.add(Calendar.WEEK_OF_YEAR, -1);
		}
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static int getDayCountOfMonth(Date time){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(time);
		return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	public static Date getNextMonday() {
		Calendar calendar = Calendar.getInstance();

		if(calendar.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
			calendar.add(Calendar.WEEK_OF_YEAR, 1);
		}
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static Date getNextNextMonday() {
		Calendar calendar = Calendar.getInstance();

		if(calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
			calendar.add(Calendar.WEEK_OF_YEAR, 1);
		} else {
			calendar.add(Calendar.WEEK_OF_YEAR, 2);
		}
		calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static Boolean isSameWeek(Date dateOne, Date dateTwo) {
		Calendar calOne = Calendar.getInstance();
		calOne.setTime(dateOne);
		Calendar calTwo = Calendar.getInstance();
		calTwo.setTime(dateTwo);
		//判断是否是周日，如果是，则其周再-1
		if(calOne.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
			calOne.add(Calendar.DATE, -1);
		}
		if(calTwo.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
			calTwo.add(Calendar.DATE, -1);
		}
		if(calOne.get(Calendar.YEAR) == calTwo.get(Calendar.YEAR) &&
				calOne.get(Calendar.WEEK_OF_YEAR) == calTwo.get(Calendar.WEEK_OF_YEAR))
		{
			return true;
		}
		int subYear = calOne.get(Calendar.WEEK_OF_YEAR) - calTwo.get(Calendar.WEEK_OF_YEAR);
		if(subYear == 1 && calTwo.get(Calendar.MONTH)==11) {
			if(calOne.get(Calendar.WEEK_OF_YEAR) == calTwo.get(Calendar.WEEK_OF_YEAR)) {
				return true;
			}
		} else if( subYear == -1 && calOne.get(Calendar.MONTH) == 11) {
			if(calOne.get(Calendar.WEEK_OF_YEAR) == calTwo.get(Calendar.WEEK_OF_YEAR)) {
				return true;
			}
		}
		return false;
	}

	public static Date getBeginningOfTheDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, 0);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static Date getTheDayAfterYesterday() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, -2);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static Date getOffsetDay(int offsetDay) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DATE, offsetDay);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return calendar.getTime();
	}

	public static Date getYearOffset(Date date,int offset) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.YEAR, offset);
		return calendar.getTime();
	}

	public static int getCurrentMonth(){
		Calendar calendar = Calendar.getInstance();
		return calendar.get(Calendar.MONTH) + 1;
	}

	public static int getCurrentYear() {
		Calendar calendar = Calendar.getInstance();
		return calendar.get(Calendar.YEAR);
	}

	public static int getLeftDaysOfThisMonth(){
		Calendar calendar = Calendar.getInstance();
		return calendar.getActualMaximum(Calendar.DAY_OF_MONTH) - calendar.get(Calendar.DAY_OF_MONTH) + 1;
	}

	public static int getDaysOfThisMonth(){
		Calendar calendar = Calendar.getInstance();
		return calendar.get(Calendar.DAY_OF_MONTH);
	}


	/**
	 * @param month  格式 yyyyMM
	 * @return 时间戳 Timestamp
	 * @throws ParseException
	 */
	public static Date getMonthTime(int month) throws ParseException {
		String dateStr = String.valueOf(month);
		Date date = null;
		if (StringUtils.isNotBlank(dateStr)) {
			SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT_YEAR_MONTH_DEFAULT);
			try {
				date = dateFormat.parse(dateStr);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}

		return date;
	}

	/**
	 * @return month 格式 yyyyMM
	 * @throws ParseException
	 */
	public static int getNowMonthTime() {
		SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT_YEAR_MONTH_DEFAULT);
		Date date = new Date();
		String month = dateFormat.format(date);
		return Integer.valueOf(month);
	}

	/**
	 * @param date 时间
	 * @return month 格式 yyyyMM
	 * @throws ParseException
	 */
	public static int getMonthTime(Date date) {
		SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT_YEAR_MONTH_DEFAULT);
		String month = dateFormat.format(date);
		return Integer.valueOf(month);
	}

	/**
	 * @return month 格式 yyyyMM
	 * @throws ParseException
	 */
	public static int getPreMonthTime() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MONTH, -1);
		SimpleDateFormat dateFormat = new SimpleDateFormat(FORMAT_YEAR_MONTH_DEFAULT);
		String month = dateFormat.format(calendar.getTime());
		return Integer.valueOf(month);
	}

	public static Date getFirstSecondOfDay(Date date) {
		return DateUtils.truncate(date, Calendar.DATE);
	}

	public static Date getLastSecondOfDay(Date date) {
		return DateUtils.addSeconds(
				DateUtils.addDays(DateUtils.truncate(date, Calendar.DATE), 1),
				-1);
	}

	public static Date getTheDayCurrentMonth(int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DATE, day);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getTheDayLastMonth(int day) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MONTH, -1);
		calendar.set(Calendar.DATE, day);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getTheFirstDayMonth() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MONTH, 0);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Boolean isAfterOtherDayCurrentMonth(Integer day){
		if (day == null) {
			return false;
		}
		Date startDate = getTheDayCurrentMonth(day);
		Date endDate = getBeginningOfNextMonth();
		Date now = new Date();
		return !startDate.after(now) && endDate.after(now);
	}

	/**
	 * 根据生日计算年龄
	 * @param birthday
	 * @return
	 * @throws ParseException
	 */
	public static Integer getAgeByBirthday(Date birthday){
		Calendar cal = Calendar.getInstance();
		if(birthday==null){
			return null;
		}
		if (cal.before(birthday)) {
			return null;
		}
		int yearNow = cal.get(Calendar.YEAR);
		int monthNow = cal.get(Calendar.MONTH) + 1;
		int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
		cal.setTime(birthday);
		int yearBirth = cal.get(Calendar.YEAR);
		int monthBirth = cal.get(Calendar.MONTH) + 1;
		int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
		int age = yearNow - yearBirth;
		if (monthNow <= monthBirth) {
			if (monthNow == monthBirth) {
				if (dayOfMonthNow < dayOfMonthBirth) {
					age--;
				}
			} else {
				age--;
			}
		}
		return age;
	}
	public static boolean isWithinXHours(final Date date, int x) {
		Calendar now = Calendar.getInstance();
		now.add(Calendar.HOUR_OF_DAY, x);
		if (date.before(now.getTime())) {
			return true;
		}
		return false;
	}

	public static Date addHours(Date date, int x) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.add(Calendar.HOUR_OF_DAY, x);
		return cal.getTime();
	}

	public static boolean isNotWithInTheDay(Date time){
		return !(time.after(DateTimeUtils.getBeginningOfTheDay()) && time.before(DateTimeUtils.getTomorrow()));
	}

	public static Date getEndOfYesterday(){
		Calendar endOfTodayCalendar = Calendar.getInstance();
		endOfTodayCalendar.add(Calendar.DATE, -1);
		endOfTodayCalendar.set(Calendar.HOUR_OF_DAY, 23);
		endOfTodayCalendar.set(Calendar.MINUTE, 59);
		endOfTodayCalendar.set(Calendar.SECOND, 59);
		endOfTodayCalendar.set(Calendar.MILLISECOND, 0);
		return endOfTodayCalendar.getTime();
	}

	public static Date getTimeOfDate(Date date, int hour, int minute, int second){
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.HOUR_OF_DAY, hour);
		cal.set(Calendar.MINUTE, minute);
		cal.set(Calendar.SECOND, second);
		return cal.getTime();
	}

	/**
	 * 计算两个时间相差的月份数据
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int getMonthsOfDate(Date date1, Date date2){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
		String date1Str = format(date1,"yyyy-MM");
		String date2Str = format(date2,"yyyy-MM");
		Calendar bef = Calendar.getInstance();
		Calendar aft = Calendar.getInstance();
		try {
			bef.setTime(sdf.parse(date1Str));
			aft.setTime(sdf.parse(date2Str));
		} catch (ParseException e) {
			logger.error("计算两个时间相差的月份数据 异常！",e);
			return 0;
		}
		int result = aft.get(Calendar.MONTH) - bef.get(Calendar.MONTH);
		int month = (aft.get(Calendar.YEAR) - bef.get(Calendar.YEAR)) * 12;
		System.out.println(Math.abs(month + result));
		return Math.abs(month + result);
	}

	/*
     * 将时间戳转换为时间
     */
	public static String stampToDate(String s){
		if(StringUtils.isBlank(s)){
			logger.error("时间为空！");
			return null;
		}
		String res;
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		long lt = new Long(s);
		Date date = new Date(lt);
		res = simpleDateFormat.format(date);
		return res;
	}
	/**
	 * 输出yyyyMMddHHmmss格式的日期字符串
	 *
	 * @param date
	 * @return
	 */
	public static String formatYYYYMMDDHHMMSS(Date date) {
		if (date == null) {
			return "";
		}
		return FORMAT_YYYYMMDDHHMMSS.format(date);
	}

	/**
	 * 输出MMddHHmmss格式的日期字符串
	 *
	 * @param date
	 * @return
	 */
	public static String formatMMDDHHMMSS(Date date) {
		if (date == null) {
			return "";
		}
		return FORMAT_MMDDHHMMSS.format(date);
	}

	/**
	 * 输出格式为yyyy-MM-dd HH:mm:ss的日期字符串
	 *
	 * @param date
	 * @return
	 */
	public static String formatYMDHMS(Date date) {
		if (date == null) {
			return "";
		}
		return FORMAT_YMDHMS.format(date);
	}

	/**
	 * 输出格式为yyyyMMdd的日期字符串
	 *
	 * @param date
	 * @return
	 */
	public static String formatYYYYMMDD(Date date) {
		if (date == null) {
			return "";
		}
		return FORMAT_YYYYMMDD.format(date);
	}

	/**
	 * 输出格式为yyyy-MM-dd的日期字符串
	 *
	 * @param date
	 * @return
	 */
	public static String formatYYYY_MM_DD(Date date) {
		if (date == null) {
			return "";
		}
		return FORMAT_YYYY_MM_DD.format(date);
	}

	/**
	 * 格式为yyyy-MM-dd的日期字符串转换成日期类型
	 */
	public static Date parseYYYY_MM_DD(String dateStr) {
		if (StringUtils.isEmpty(dateStr)) {
			return null;
		}
		DateTime dateTime = PARSER_YYYY_MM_DD.parseDateTime(dateStr);
		return dateTime.toDate();
	}

	/**
	 * 解析格式为yyyyMMddHHMMSS的日期字符串
	 *
	 * @param dateString
	 * @return
	 */
	public static Date parseYYYYMMDDHHMMSS(String dateString) {
		if (StringUtils.isEmpty(dateString)) {
			return null;
		}
		DateTime dateTime = PARSER_YYYYMMDDHHMMSS.parseDateTime(dateString);
		return dateTime.toDate();
	}

	/**
	 * 解析格式为yyyy-MM-dd HH:mm:ss的日期字符串
	 *
	 * @param dateString
	 * @return
	 */
	public static Date parseYMDHMS(String dateString) {
		if (StringUtils.isEmpty(dateString)) {
			return null;
		}
		DateTime dateTime = PARSER__YMDHMS.parseDateTime(dateString);
		return dateTime.toDate();
	}

	/**
	 * 解析格式为yyyyMMdd的日期字符串
	 *
	 * @param dateString
	 * @return
	 */
	public static Date parseYYYYMMDD(String dateString) {
		if (StringUtils.isEmpty(dateString)) {
			return null;
		}
		DateTime dateTime = PARSER__YYYYMMDD.parseDateTime(dateString);
		return dateTime.toDate();
	}

	/**
	 * 计算播放时长，返回 HH:mm:ss
	 *
	 * @param seconds time in seconds.
	 * @return time string in HH:mm:ss format.
	 */
	public static String formatHHMMSS(long seconds) {
		return formatHHMMSS(seconds, false);
	}

	/**
	 * 计算播放时长，返回 HH:mm:ss
	 *
	 * @param seconds time in seconds.
	 * @return time string in HH:mm:ss format.
	 */
	public static String formatHHMMSS(long seconds, boolean trimPrefix) {
		StringBuilder result = new StringBuilder();
		long[] time = new long[3];
		time[0] = seconds / 3600; // 时
		time[1] = (seconds % 3600) / 60; // 分
		time[2] = (seconds % 3600) % 60; // 秒
		boolean end = false;
		for (int i = 0; i < 3; i++) {
			long v = time[i];
			if (v == 0 && trimPrefix && !end) {
				continue;
			}
			end = true;
			if (v < 10) {
				result.append("0");
			}
			result.append(v);
			if (i == 2) {
				return result.toString();
			}
			result.append(":");
		}
		return result.toString();
	}

	public static int daysBetween(Long smdate, Long bdate) {
		long between_days = (bdate - smdate) / (1000 * 3600 * 24);

		return Integer.parseInt(String.valueOf(between_days));
	}

	public static int daysBetween(Date smdate, Date bdate) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			smdate = sdf.parse(sdf.format(smdate));
			bdate = sdf.parse(sdf.format(bdate));
			Calendar cal = Calendar.getInstance();
			cal.setTime(smdate);
			long time1 = cal.getTimeInMillis();
			cal.setTime(bdate);
			long time2 = cal.getTimeInMillis();
			long between_days = (time2 - time1) / (1000 * 3600 * 24);
			return Integer.parseInt(String.valueOf(between_days));
		} catch (ParseException e) {
			return 0;
		}

	}

	public static Date getDayStartTime(Date d) {
		Calendar calendar = Calendar.getInstance();
		if (null != d) {
			calendar.setTime(d);
		}
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getDayEndTime(Date d) {
		Calendar calendar = Calendar.getInstance();
		if (null != d) {
			calendar.setTime(d);
		}
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	//获取当前时间之前或之后某天的时间
	public static Date getFirstDate(Date d, int dayCount) {
		Calendar calendar = Calendar.getInstance();
		if (null != d) {
			calendar.setTime(d);
		}
		calendar.add(Calendar.DAY_OF_YEAR, -dayCount);
		return calendar.getTime();
	}

	public static Date getPastYear(Date d, int yearCount) {
		Calendar calendar = Calendar.getInstance();
		if (null != d) {
			calendar.setTime(d);
		}
		calendar.add(Calendar.YEAR, -yearCount);
		return calendar.getTime();
	}

	//本年第一天
	public static Date getFirstDayOfYear(Date d) {
		Calendar calendar = Calendar.getInstance();
		if (null != d) {
			calendar.setTime(d);
		}
		calendar.set(calendar.get(Calendar.YEAR), 0, 1, 0, 0, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	//本年最后一天的23点59分
	public static Date getLastDayOfYear(Date d) {
		Calendar calendar = Calendar.getInstance();
		if (null != d) {
			calendar.setTime(d);
		}
		calendar.set(calendar.get(Calendar.YEAR), 11, 31, 23, 59, 59);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	//当月第一天的零点零分
	public static Date getThisMonthFirstDayStartTime() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		Date sdate = calendar.getTime();
		return sdate;
	}

	//本月月最后一天的23点59分
	public static Date getThisMonthLastDayEndTime() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		calendar.add(Calendar.MONTH, 1);
		calendar.add(Calendar.MILLISECOND, -1);
		Date edate = calendar.getTime();
		return edate;
	}





}
